﻿using System.Windows;
using ModelingProjectLib.Interfaces;
using System.Diagnostics;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;

namespace INSAwarsWPF
{
    /// <summary>
    /// Logique d'interaction pour GameWindow.xaml
    /// </summary>
    public partial class GameView : Window
    {
        public GameViewModel ViewModel { get; set; }
        // public Grid GrilleJeu { get; set; }

        public GameView(Partie partie)
        {
            ViewModel = new GameViewModel(this, partie);
            InitializeComponent();

            DataContext = ViewModel; // important ! (à mettre ici ou dans le xaml)
        }

        private void buttonQuitter_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void buttonFinTour_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.Joueurs.joueurSuivant(); // les propriétés seront mises à jour automatiquement (binding)
            ViewModel.majViewChangementJoueur();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (MessageBox.Show("Voulez-vous vraiment quitter ?", "Confirmation", MessageBoxButton.YesNo)
                == MessageBoxResult.Yes)
                e.Cancel = false;
            else
                e.Cancel = true;
        }

        private void buttonCreerVille_Click(object sender, RoutedEventArgs e)
        {
            // a améliorer sûrement
            bool nomOk = false;
            string nom;
            do
            {
                DemanderNomVilleView dialog = new DemanderNomVilleView("Ville-"
                + ViewModel.PartieCourante.JoueurCourant.Nom +
                "-" + (ViewModel.PartieCourante.JoueurCourant.Civilisation.ListVilles.Count + 1));

                dialog.Owner = this;
                dialog.ShowDialog();

                nomOk = dialog.ResultOk;
                nom = dialog.ResultString;
            } while (!nomOk);


            // rajout d'une ville à la carte et à la liste des villes
            Ville v = ViewModel.PartieCourante.JoueurCourant.Civilisation.creerVille(ViewModel.SelectedCase.Row, ViewModel.SelectedCase.Column, nom);

            // on supprime l'enseignant
            ViewModel.SelectedCase.SelectedUnite.supprimer();

            ViewModel.SelectedCase.VilleCase = new VilleViewModel(ViewModel.SelectedCase, v);
            //ViewModel.majCreationVille();
        }

        private void Unite_KeyUp(object sender, KeyEventArgs e)
        {
            
            switch (e.Key.ToString())
            {
                case "Z":
                    ViewModel.SelectedCase.SelectedUnite.deplacerHaut();
                    break;
                case "Q":
                    ViewModel.SelectedCase.SelectedUnite.deplacerGauche();
                    break;
                case "S":
                    ViewModel.SelectedCase.SelectedUnite.deplacerBas();
                    break;
                case "D":
                    ViewModel.SelectedCase.SelectedUnite.deplacerDroite();
                    break;
                default:
                    break;
            }

            e.Handled = true;
        }

        private void ListBoxUnites_Loaded(object sender, RoutedEventArgs e)
        {
            // donne le focus à l'élément sélectionné au démarrage 
            ListBox lb = sender as ListBox;
            if (lb.Items.Count > 0)
            {
                CaseViewModel selectedCase = ListBoxJeu.SelectedItem as CaseViewModel;
                UniteViewModel selectedUnite = lb.SelectedItem as UniteViewModel;

                if (selectedCase.SelectedUnite == selectedUnite)
                {
                    ListBoxItem lbi = (ListBoxItem)lb.ItemContainerGenerator.ContainerFromItem(selectedUnite);
                    Keyboard.Focus(lbi);
                }
            }
            //Keyboard.Focus(item);
        }

        private void ListBoxJeu_Loaded(object sender, RoutedEventArgs e)
        {
            // exécuté avant tous les ListBoxUnites_Loaded
            ListBoxJeu.ScrollIntoView(ViewModel.SelectedCase);
        }

        public void focusOnSelectedUnite()
        {
            ListBoxItem selectedCaseLB = ListBoxJeu.ItemContainerGenerator.ContainerFromItem(ViewModel.SelectedCase) as ListBoxItem;
            ListBox lbUnites = FindDescendant<ListBox>(selectedCaseLB);

            ListBoxItem selectedUniteLB = lbUnites.ItemContainerGenerator.ContainerFromItem(ViewModel.SelectedCase.SelectedUnite) as ListBoxItem;
            Keyboard.Focus(selectedUniteLB);

            // à faire aussi : scroller la vue pour se centrer sur la case sélectionnée
        }

        /** Méthode qui permet de parcourir les descendants d'un élément dans le XAML :
         * utile pour les descendants d'une ListBox */
        private T FindDescendant<T>(DependencyObject obj) where T : DependencyObject
        {
            // Check if this object is the specified type
            if (obj is T)
                return obj as T;

            // Check for children
            int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
            if (childrenCount < 1)
                return null;

            // First check all the children
            for (int i = 0; i < childrenCount; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child is T)
                    return child as T;
            }

            // Then check the childrens children
            for (int i = 0; i < childrenCount; i++)
            {
                DependencyObject child = FindDescendant<T>(VisualTreeHelper.GetChild(obj, i));
                if (child != null && child is T)
                    return child as T;
            }

            return null;
        }
    }
}
